﻿using System.IO;
using System.Web.UI;
using visinia.SmartEngine.Installer;
namespace visinia.SmartEngine.Modules
{
    /// <summary>
    /// WebModule is the actual part of the visinia module which is displayed on the webpage
    /// WebModule is derived from the BaseModule which holds this module private settings.
    /// Every visinia module must derived from this class or class which derives from the WebModule class.
    /// This class renders the module on the webpage.
    /// visinia has two rendering modes a normal mode or user mode, in this mode the module is 
    /// rendered on the page as normal, this the visinia page production version.
    /// The other mode is designer mode, this mode is used to set the webpage layout, to add new modules
    /// delete a module or to update a module settings, visinia has a powerful dragdrop module support, 
    /// visinia module can be draged and dropped anywhere on the webpage, and can be staked in any required
    /// order, this feature is framed through the jquery.    
    /// </summary>
    public class WebModule : BaseModule
    {
        /// <summary>
        /// Override if a direct content rendering is required
        /// </summary>
        /// <param name="writer"></param>
        protected internal virtual void WebModuleRender(HtmlTextWriter writer)
        { }

        /// <summary>
        /// The visinia module actual rendering 
        /// </summary>
        /// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            if (writer == null)
                return;
            if (WebModuleController.CURRENT_MODE == WebModuleController.MODES.DESIGNER)
            {
                writer.Write(DesignModeRender());
            }
            else
            {
                writer.Write(Render());
            }
        }

        /// <summary>
        /// This is the user mode rendering version of the visinia module.
        /// When a normal user will see visinia run site this mothod will be called.
        /// A very self explanatory method, taked care of the module width height and
        /// module title and actual module rendering through
        /// base.Render(new HtmlTextWriter(tempWriter)); 
        /// </summary>
        /// <returns></returns>
        private string Render()
        {
            StringWriter stringWriter = new StringWriter();
            //get the module properties which is required to render
            ModuleInfo module = ModuleController.GetModule(ModuleId);
            //the code below only renders the module properties if they exist            
            string css = module.CssClass;
            if ( ! module.Visible)
                css += " hidden-module";
            // I just put the module id here as the div id may be of any use
            // but the id is appended with the 'Module_' strings (so no one can complain about generated html)
            stringWriter.Write("<div class=\"" + css + " module-container\"  id=\"Module_" + module.ModuleId + "\" style=\"");
            if (module.Width > 0)
                stringWriter.Write(" width: " + module.Width + "px; ");
            if (module.Height > 0)
                stringWriter.Write(" height: " + module.Height + "px; ");
            stringWriter.Write("\" >");
            // only render module title if it is specified in module properties
            // otherwise just skip, no linebreak </br> is used
            // as some module may require immediate rendering below another module without gap
            if (!string.IsNullOrEmpty(module.Title))
                stringWriter.Write("<h2 class=\"module-title\">" + module.Title);
            if (!string.IsNullOrEmpty(module.TitleImageUrl))
            {
                string imageUrl = module.TitleImageUrl;
                if (!module.TitleImageUrl.StartsWith("http://"))
                    imageUrl = WebRoots.GetWebRoot + module.TitleImageUrl;

                string imageNavigationUrl = module.TitleImageNavigationUrl;
                if (!module.TitleImageNavigationUrl.StartsWith("http://"))
                    imageNavigationUrl = WebRoots.GetWebRoot + module.TitleImageNavigationUrl;

                if (!string.IsNullOrEmpty(imageUrl))
                {
                    stringWriter.Write("<a href=\"" + imageNavigationUrl + "\" >");
                    stringWriter.Write("<img class=\"module-title-image\" src=\"" + imageUrl + "\" alt=\"" + imageNavigationUrl + "\" />");
                    stringWriter.Write("</a>");
                }
            }
            if (!string.IsNullOrEmpty(module.Title))
                stringWriter.Write("</h2>");

            stringWriter.Write("<div class=\"module-body\">");
            base.Render(new HtmlTextWriter(stringWriter));
            // this version used for the modules who override WebModuleRender 
            WebModuleRender(new HtmlTextWriter(stringWriter));
            stringWriter.Write("</div>"); // closes module-body 

            stringWriter.Write("</div>"); // closes module-container 
            return stringWriter.ToString();
        }

        /// <summary>
        /// The DesignModeRender is called when visinia webpage is running in designer mode
        /// this version of the render actually is a bit complex, the matter is 
        /// module drag drop support which makes this method a bit complex.
        /// This method also renders module with the specified height width and title as the
        /// normal render does.
        /// The added portion is to support module drag drop.
        /// Every module is rendered inside a div with the class name dragbox. This is the div
        /// which jquery uses as an entity to move. 
        /// </summary>
        /// <returns></returns>
        private string DesignModeRender()
        {
            StringWriter stringWriter = new StringWriter();            
            ModuleInfo module = ModuleController.GetModule(ModuleId);
            // render module inside dragbox div for drag drop support
            stringWriter.Write("<div class=\"dragbox\" id=\"" + module.ModuleId + "\">");
            stringWriter.Write("<div class=\"title-bar\">" + ModulesInstalledController.GetInstalledModule(module.ModuleInstalledId).Name);
            if (!module.Visible)            
                stringWriter.Write("<span class=\"Hidden\" >Hidden Module</span>");            
                stringWriter.Write("<span class=\"buttons\" >");
                    stringWriter.Write("<a title=\"Expand/Collapse\" class=\"expand-collapse\" href=\"#Expand-Collapse\" >&nbsp;</a>");
                    stringWriter.Write("<a title=\"Settings\" class=\"configure\" href=\"#Configure" + module.ModuleId + "\" >&nbsp;</a>");
                    stringWriter.Write("<a title=\"Help\" class=\"help\" href=\"#Help" + module.ModuleId + "\" >&nbsp;</a>");
                    stringWriter.Write("<a title=\"Delete\" class=\"delete\" href=\"#Delete" + module.ModuleId + "\" >&nbsp;</a>");                    
                stringWriter.Write("</span>");
            stringWriter.Write("</div>");
            stringWriter.Write("<div class='dragbox-content'>");
            
            stringWriter.Write(Render());            

            stringWriter.Write("</div>");            
            stringWriter.Write("</div>");
            return stringWriter.ToString();
        }
    }
}
